package com.silence.springboot.service.impl;


import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.silence.springboot.convert.BookBaseConvert;
import com.silence.springboot.dao.BookBaseDao;
import com.silence.springboot.dto.BookStatusJoinAuthorDto;
import com.silence.springboot.entity.BookBaseEntity;
import com.silence.springboot.mapper.BookBaseMapper;
import com.silence.springboot.service.BookBaseService;
import com.silence.springboot.vo.input.*;
import com.silence.springboot.vo.output.PageBookBaseInfoOutput;
import com.silence.springboot.vo.output.PageBookStatusAdminOutput;
import com.silence.springboot.vo.output.PageBookStatusOutput;
import com.silence.springboot.vo.output.SelectAllOutput;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;

/**
 * 图书信息表 服务层实现。
 *
 * @author mybatis-flex-helper automatic generation
 * @since 1.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class BookBaseServiceImpl extends ServiceImpl<BookBaseMapper, BookBaseEntity> implements BookBaseService {

    /**
     * 图书信息表 转换类
     */
    private final BookBaseConvert bookBaseConvert;

    /**
     * 图书信息表 数据访问层实现
     */
    private final BookBaseDao bookBaseDao;

    /**
     * 新建入库
     *
     * @param input 作者信息表入参
     */
    @Override
    public void insertBook(InsertBookInput input) {
        // 转换实体类
        BookBaseEntity entity = bookBaseConvert.insertBookInputToBookBaseEntity(input);
        // 查询数据库中的作者编号
        bookBaseDao.insertBookByQuery(entity);
    }

    /**
     * 查询信息
     *
     * @param input 图书信息表实体类
     * @return 图书信息表实体类
     */
    @Override
    public BookBaseEntity selectBook(SelectBookInput input) {
        // 获取图书编号
        Long id = Long.parseLong(input.getBookId());
        // 查询数据库中的图书信息
        return bookBaseDao.selectBookByQuery(id);
    }


    /**
     * 新建入库
     *
     * @param input 作者信息表入参
     */
    @Override
    public void updateBook(UpdateBookInput input) {
        // 转换实体类
        BookBaseEntity entity = bookBaseConvert.updateBookInputToBookBaseEntity(input);
        // 查询数据库中的作者编号
        bookBaseDao.updateBookByQuery(entity);
    }

    /**
     * 分页查询图书信息
     *
     * @param input 入参
     * @return 分页结果
     */
    @Override
    public Page<PageBookBaseInfoOutput> pageBookBaseInfo(PageBookBaseInfoInput input) {
        // 查询数据库中的图书信息
        return bookBaseDao.pageBookBaseInfoByQuery(input.getPageNumber(), input.getPageSize(), input.getBookName(), input.getAuthorName())
                .map(bookBaseConvert::toPageBookBaseInfoOutput);
    }

    /**
     * 删除图书信息
     *
     * @param id 主键
     */
    @Override
    public void deleteBook(String id) {
        bookBaseDao.deleteBook(Long.parseLong(id));
    }

    /**
     * 查询所有图书信息
     *
     * @return 所有图书信息
     */
    @Override
    public List<SelectAllOutput> selectAll() {
        // 查询数据库中的图书信息
        return bookBaseConvert.toSelectAllOutputList(bookBaseDao.selectAll());
    }

    /**
     * 借书
     *
     * @param input 入参
     */
    @Override
    public void borrowBook(BorrowBookInput input) {
        bookBaseDao.borrowBook(input.getId(), input.getBorrowName());
    }

    /**
     * 还书
     *
     * @param input 入参
     */
    @Override
    public void returnBook(ReturnBookInput input) {
        bookBaseDao.returnBook(input.getId(), input.getReturnName());
    }

    /**
     * 分页查询图书状态
     *
     * @param input 入参
     * @return 分页结果
     */
    @Override
    public Page<PageBookStatusOutput> pageBookStatus(PageBookStatusInput input) {
        Page<BookStatusJoinAuthorDto> dtoPage = bookBaseDao.pageBookStatus(input.getPageNumber(), input.getPageSize(),
                input.getName(), input.getBookName(), input.getAuthorName());
        return dtoPage.map(item -> {
            // 转换实体类
            PageBookStatusOutput pageBookStatusOutput = bookBaseConvert.toPageBookStatusOutput(item);
            // 获取借阅时间
            LocalDateTime borrowTime = item.getBorrowTime();
            if (Objects.nonNull(borrowTime)) {
                String term = item.getTerm();
                // 计算应还时间
                LocalDateTime limitReturnTime = borrowTime.plusDays(Objects.nonNull(term) ? Long.parseLong(term) : 180L);
                pageBookStatusOutput.setLimitReturnTime(limitReturnTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }
            return pageBookStatusOutput;
        });
    }

    /**
     * 分页查询图书状态
     *
     * @param input 入参
     * @return 分页结果
     */
    @Override
    public Page<PageBookStatusAdminOutput> pageBookStatusAdmin(PageBookStatusAdminInput input) {
        // 查询数据库中的图书状态
        return bookBaseDao.pageBookStatus(input.getPageNumber(), input.getPageSize(),
                        input.getBookName(), input.getBookAuthorName())
                .map(bookBaseConvert::toPageBookStatusAdminOutput);
    }

    /**
     * 管理员同意借书或还书
     *
     * @param input 入参
     */
    @Override
    public void adminAgreeBorrowOrReturn(AdminAgreeBorrowOrReturnInput input) {
        // 获取图书id
        String id = input.getId();
        // 获取图书状态
        String bookStatus = input.getBookStatus();
        // 判断图书状态是借阅还是归还
        if ("1".equals(bookStatus)) {
            // 更新图书状态
            bookBaseDao.updateAgreeBorrowBookStatus(Long.parseLong(id));
        } else {
            // 更新图书状态
            bookBaseDao.updateAgreeReturnBookStatus(Long.parseLong(id));
        }
    }

    /**
     * 管理员拒绝借书或还书
     *
     * @param input 入参
     */
    @Override
    public void adminRefuseBorrowOrReturn(AdminRefuseBorrowOrReturnInput input) {
        // 获取图书id
        String id = input.getId();
        // 获取图书状态
        String bookStatus = input.getBookStatus();
        // 查询数据库中的图书信息
        BookBaseEntity bookBaseEntity = bookBaseDao.selectBookByQuery(Long.parseLong(id));
        String returnBookName = bookBaseEntity.getReturnBookName();
        LocalDateTime returnTime = bookBaseEntity.getReturnTime();
        if ("1".equals(bookStatus)) {
            // 更新图书状态
            bookBaseDao.updateRefuseBorrowBookStatus(Long.parseLong(id));
        } else {
            // 更新图书状态
            bookBaseDao.updateRefuseReturnBookStatus(Long.parseLong(id), returnBookName, returnTime);
        }
    }
}